using System;
using System.Collections.Generic;
using System.Linq;
using LitJson;
using UnityEngine;
using Yoozoo.Managers.ResourceManagerV2.Runtime;

public static class WorldNavData
{
    public const int GRID_FACTOR = 100000;
    
    public static MapPartMeshData MapPartMeshData;

    private static object navDataAsset;
    
    public static void Preload(Action callback)
    {
        string jsonPath = "Assets/ResourcesAssets/Config/Data/mapShapeData.json";
        var resLoader = ResLoader.Alloc();

        resLoader.Add2Load(jsonPath, typeof(UnityEngine.TextAsset), (success, name, asset) =>
        {
            navDataAsset = asset;
        });

        resLoader.Load((() =>
        {
            callback?.Invoke();
        }));
    }
    
    public static void Init()
    {
        var txtAsset = navDataAsset as UnityEngine.TextAsset;
        
        JsonMapper.RegisterImporter<double, float>(input => Convert.ToSingle(input));
        var NavMeshInfo = JsonMapper.ToObject<NavMeshInfo>(txtAsset.text);
        
        JsonMapper.UnregisterImporters();
        
        MapPartMeshData = new MapPartMeshData();
        MapPartMeshData.GridHeight = NavMeshInfo.gridSize.x;
        MapPartMeshData.GridWidth = NavMeshInfo.gridSize.y;
        
        for (int i = 0; i < NavMeshInfo.partNavInfos.Length; i++)
        {
            PartMeshData meshData = new PartMeshData();

            meshData.PartName = NavMeshInfo.partNavInfos[i].partName;
            
            // 存入HashSet 是否存在判断速度更快~
            foreach (var wrapIdx in NavMeshInfo.partNavInfos[i].wrapGrid)
            {
                meshData.WrapGrid.Add(wrapIdx);
            }
            
            foreach (var wrapIdx in NavMeshInfo.partNavInfos[i].crossGrid)
            {
                meshData.CrossGrid.Add(wrapIdx);
            }
            
            meshData.Points = NavMeshInfo.partNavInfos[i].points;
            
            MapPartMeshData.MeshData.Add(meshData);
        }
    }

    /// <summary>
    /// 得到点所在的分块名
    /// </summary>
    /// <param name="x"></param>
    /// <param name="y"></param>
    /// <returns></returns>
    public static string GetPosMeshPart(float x, float y)
    {
        if (x < 0 || y < 0 || x > 1200 || y > 1200) 
        {
            return "";
        }
        
        // 1、得到点所在格子
        int gridIndex = ((int) (x / MapPartMeshData.GridWidth)) * GRID_FACTOR + (int) (y / MapPartMeshData.GridHeight);
        // 2、判断格子是否被某个分块包含
        foreach (var partMeshData in MapPartMeshData.MeshData)
        {
            if (partMeshData.WrapGrid.Contains(gridIndex))
            {
                return partMeshData.PartName;
            }
        }
        
        // 3、检测交叉格子
        List<PartMeshData> partMeshDatas = new List<PartMeshData>();
        
        foreach (var partMeshData in MapPartMeshData.MeshData)
        {
            if (partMeshData.CrossGrid.Contains(gridIndex))
            {
                partMeshDatas.Add(partMeshData);
                
                // 检测是否在多边形内
                if (PointInPolygon.isInside(partMeshData.Points,partMeshData.Points.Length,new Vector2(x,y)))
                {
                    return partMeshData.PartName;
                }
            }
        }

        // 所有多边形内都没找到 那么返回第一个
        if (partMeshDatas.Count > 0)
        {
            return partMeshDatas[0].PartName;
        }
        
        return "";
    }
    
}


public class MapPartMeshData
{
    public MapPartMeshData()
    {
        MeshData = new List<PartMeshData>();
    }
    
    /// <summary>
    /// 格子宽度
    /// </summary>
    public int GridWidth;
    /// <summary>
    /// 格子高度
    /// </summary>
    public int GridHeight;

    /// <summary>
    /// 分块Mesh数据
    /// </summary>
    public List<PartMeshData> MeshData;
}

public class PartMeshData
{
    public PartMeshData()
    {
        WrapGrid = new HashSet<int>();
        CrossGrid = new HashSet<int>();
    }
    
    /// <summary>
    /// 分块名
    /// </summary>
    public string PartName;
    /// <summary>
    /// Mesh多边形顶点
    /// </summary>
    public Vector2[] Points;
    /// <summary>
    /// 全部在此Mesh多边形内的格子索引
    /// </summary>
    public HashSet<int> WrapGrid; 
    /// <summary>
    /// 部分在此Mesh多边形的格子索引（可能与其它Mesh重合的格子索引）
    /// </summary>
    public HashSet<int> CrossGrid;
}


public class NavMeshInfo
{
    public Vector2Int gridSize;
    
    public PartNavMeshInfo[] partNavInfos;
}

public class PartNavMeshInfo
{
    public string partName;
    public Vector2[] points;
    public int[] wrapGrid;
    public int[] crossGrid;
}


